package generator.workflow.sfj;

import generator.datastructure.ForkPoint;
import generator.datastructure.MethodDeclaration;
import generator.datastructure.VarDeclaration;
import generator.workflow.PeerClassBuilder;

import java.util.List;

public interface SFJPeerClassBuilder extends PeerClassBuilder {
	
	/**@param md
	 * 			indica el método dentro del cual se debe realizar la búsqueda de forks o llamados 
	 * 			recursivos.
	 * @return retorna la lista de asignaciones en las que del lado derecho se encuentra un llamado 
	 * recursivo dentro del método que se pretende gridificar*/
	public List<ForkPoint> getForks(MethodDeclaration md);



	/**Dado un fork perteneciente a un método, lo transforma de manera que represente una creación
	 * y envío de un trabajo al grid. El resultado del trabajo debe ser alojado en un
	 * objeto tipo {@link java.util.concurrent.Future}. 
	 * Si el fork contiene la declaración de la variable grid (la que se supone alojará el resultado
	 * que se obtenga de la ejecución del mismo), esta será reemplazada por la correspondiente declaración
	 * del future.
	 * Por el contrario, si el fork no contiene la declaración de la variable grid (sino la referencia
	 * a esta), la declaración del future deberá realizarse del siguiente modo: reemplazar la referencia
	 * a la variable grid por una referencia a la variable future y declarar el future de forma aislada
	 * en la línea inmediata posterior a donde se encuentre la declaración de la variable grid.
	 * @param fork
	 * 			representa el llamado recursivo que pretende convertirse en un trabajo para que su
	 * 			ejecución pueda realizarse utilizando los servicios de algún middleware de gridificación.
	 * @return un fork que representa una sentencia en la que el llamado recursivo se encuentra transformado
	 * 			en un trabajo cuya ejecución hará uso de los servicios de algún middleware de gridificación.*/
	public ForkPoint gridEnableFork(ForkPoint fork);



	/**Dado un fork perteneciente a un método, devuelve una referencia a la declaración
	 * aislada de la variable grid destinada a alojar el resultado de la ejecución del fork.
	 * Aislada significa a que no recibe valor inicial, es decir, es de la forma "Tipo NombreVariable;"
	 * Si en la misma sentencia del fork se encuentra incluida la delcaración de dicha variable,
	 * la misma se vuelve a declarar sin asignación de valor en la línea inmediata anterior al fork
	 * y se devuelve la referencia a esa nueva declaración.
	 * Si el fork no incluye la declaración de la variable grid, se devuelve la referencia de 
	 * la primer declaración encontrada partiendo desde el fork hacia arriba.
	 * NOTA: en cualquier caso, la línea correspondiente al fork no debe sufrir alteraciones
	 * @param fork
	 * 			sentencia que contiene un fork o llamado recursivo al método que se pretende gridificar
	 * @return una referencia a la declaración aislada de la variable grid destinada a alojar el
	 * 		   resultado de la ejecución del fork*/
	public VarDeclaration isolateGridVariableDeclaration(ForkPoint fork);

	
	/**Dado la declaración de una variable grid y la sentencia fork transformada de manera que 
	 * represente un trabajo a ser ejecutado en un grid, deberán establecerse las modificaciones
	 * necesarias que permitan, en cada referencia a la variable grid, posterior al fork gridificado,
	 * que se encuentre dentro del ámbito de declaración, obtener el valor que aloja el Future asociado
	 * a dicha variable grid.
	 * La implementación de este binding no impone restricción alguna sobre la estructura de 
	 * la clase a gridificar.
	 * @param gridVariableDec declaración de la variable que obtiene su valor del cálculo en el grid.
	 * @param gridifiedFork punto de Fork a partir del cual el valor de la variable es el calculado en el grid. 
	 */
	public void setJoinPoints(VarDeclaration gridVariableDec, ForkPoint gridifiedFork);

}
